const { Menu } = require('../models/Middle')
const { Op } = require('sequelize')
const moment = require('moment')
const seq = require('../utils/seq')

// 新增
async function add (menu) {
  menu.ctime = moment().format('YYYY-MM-DD HH:mm:ss')
  menu.mtime = moment().format('YYYY-MM-DD HH:mm:ss')
  try {
    return await Menu.create(menu)
  } catch (error) {
    throw error
  }
}

// 查询（分页、排序、模糊查询搜索、查询状态）
/**
 * limit 提取多少行，offset 跳过多少行
 * @param {*} page 当前页码
 * @param {*} size 每页条数
 */
async function findAll (query) {
  try {
    const size = query.size ? parseInt(query.size) : 10 // 如果没传参数设置一个默认值
    const page = query.page ? parseInt(query.page) : 1
    const { count, rows } = await Menu.findAndCountAll({
      include: [
        {
          required: false,
          model: Menu,
          as: 'children',
          where: {
            status: {
              [Op.like]:  query.status ? `%${JSON.parse(query.status) ? 1 : 0}%` : '%%'
            }
          },
          include: [
            {
              required: false,
              model: Menu,
              as: 'children',
              where: {
                status: {
                  [Op.like]:  query.status ? `%${JSON.parse(query.status) ? 1 : 0}%` : '%%'
                }
              }
            }
          ]
        }
      ],
      where: {
        pid: null,
        status: {
          [Op.like]: query.status ? `%${JSON.parse(query.status) ? 1 : 0}%` : '%%' // 查询状态
        },
        [Op.or]: [ // 模糊查询
          { name: { [Op.like]: query.search ? `%${query.search}%` : '%%' } },
          { icon: { [Op.like]: query.search ? `%${query.search}%` : '%%' } },
          { path: { [Op.like]: query.search ? `%${query.search}%` : '%%' } },
          { component: { [Op.like]: query.search ? `%${query.search}%` : '%%' } },
          { type: { [Op.like]: query.search ? `%${query.search}%` : '%%' } },
          { remark: { [Op.like]: query.search ? `%${query.search}%` : '%%' } },
          { ctime: { [Op.like]: query.search ? `%${query.search}%` : '%%' } },
          { mtime: { [Op.like]: query.search ? `%${query.search}%` : '%%' } }
        ],
      },
      offset: (page - 1) * size,
      limit: size,
      order: [
        [query.order ? query.order : 'ctime', query.sort ? query.sort : 'desc'] // 使用 Element 表格中的排序是互斥的，所以每次排序只能排一个元素的
      ],
      distinct: true, // 避免分页出的总数和实际数不匹配
    })
    return {
      count,
      data: rows
    }
  } catch (error) {
    throw error
  }
}

// 修改
async function update (menu) {
  menu.mtime = moment().format('YYYY-MM-DD HH:mm:ss')
  try {
    return await Menu.update(menu, {
      where: {
        id: menu.id
      }
    })
  } catch (error) {
    throw error
  }
}

// 删除，先删除菜单相关联的表
async function deleteById (id) {
  try {
    await seq.query(`delete from role_menu where menuId='${id}'`)
    return await Menu.destroy({
      where: {
        id
      }
    })
  } catch (error) {
    throw error
  }
}

// 根据id查询
async function findOneById (id) {
  try {
    const menu = await Menu.findOne({
      where: {
        id
      }
    })
    let father = {}
    if (menu.pid) {
      father = await Menu.findOne({
        where: {
          id: menu.pid
        }
      })
    }
    return {menu, father}
  } catch (error) {
    throw error
  }
}

/**
 * 根据菜单ids递归出嵌套菜单
 * @param {*} ids 
 * @returns 
 */
async function getMenuTree (ids) {
  try {
    const data = await Menu.findAll({
      where: {
        id: {
          [Op.in]: ids
        }
      },
      raw: true
    })
    // 存储父节点
    let parent = []
    data.forEach(item => {
      if (item.pid === '' || item.pid === null) {
        item.children = getChildTree(item.id, data)
        parent.push(item)
      }
    })
    return parent
  } catch (error) {
    throw error
  }
}


// 获取子节点下的数据
function getChildTree (pid, data) {
  let children = []
  // 判断item.pid 是否等于 pid
  data.forEach(item => {
    if (item.pid === pid) {
      children.push(item)
    }
  })
  children.forEach(item => {
    const list = getChildTree(item.id, data)
    if (list.length !== 0) {
      item.children = list
    } else {
      item.children = []
    }
  })
  return children
}

module.exports = {
  add,
  findAll,
  update,
  deleteById,
  findOneById,
  getMenuTree
}